package com.zc.security.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zc.security.constants.RedisConstants;
import com.zc.security.domain.LoginUser;
import com.zc.security.domain.User;
import com.zc.security.dto.UserDto;
import com.zc.security.mapper.UserMapper;
import com.zc.security.service.UserService;
import com.zc.security.utils.JwtUtils;
import com.zc.security.utils.RedisCache;
import com.zc.security.utils.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    @Override
    public ResponseData<String> login(UserDto userDto) {
        try {
            //调用 AuthenticationManager authenticate进行用户认证
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDto.getUserName(), userDto.getPassword());
            Authentication authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
            //如果认证没通过，给出对应的提示
            if (Objects.isNull(authenticate)) {
                ResponseData.fail(500, "登录失败");
            }

            //如果认证通过了，使用userId生成一个TOKEN，并将TOKEN响应给前端
            LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
            String token = JwtUtils.createJwtToken(loginUser.getUser().getId());
            //把完整的用户信息存入redis，userid作为key,value为LoginUser对象,过期时间30分钟
            redisCache.setCacheObject(RedisConstants.LOGIN_USER_KEY + loginUser.getUser().getId(), loginUser, RedisConstants.LOGIN_USER_EXPIRE_TIME, TimeUnit.SECONDS);
            return ResponseData.ok(token);
        } catch (RuntimeException e) {
            log.error(e.getMessage());
            return ResponseData.fail(500, e.getMessage());
        }


    }

    @Override
    public ResponseData<String> logout() {
        //获取SecurityContextHolder中的用户id
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();

        //删除redis中的值
        redisCache.deleteObject(RedisConstants.LOGIN_USER_KEY + loginUser.getUser().getId());

        return ResponseData.ok("注销成功");
    }
}
